// structTest
package main

import (
	"fmt"
)

type Address struct {
	province string
	city     string
}

type User3 struct {
	id   int
	name string

	Address // 内嵌，可以实现类似继承的用法，如下面获取 province
}

// 值传递，深拷贝
func updateName1(u User3) {
	u.name = u.name + "1"
}

// 引用传递，浅拷贝
func updateName2(u *User3) {
	u.name = u.name + "2"
}

func main() {
	u1 := User3{id: 1, name: "zxy"}
	u2 := User3{id: 2, name: "zxy"}

	updateName1(u1)
	fmt.Println("u1:", u1)
	updateName2(&u2)
	fmt.Println("u2:", u2)

	u3 := User3{id: 3, name: "zxy", Address: Address{province: "广东", city: "深圳"}}
	fmt.Println("u3.name:", u3.name)
	fmt.Println("u3.Address.province:", u3.Address.province)
	// 内嵌后，province 就跟继承来的，一样可以使用了
	fmt.Println("u3.province:", u3.province)

	u4 := User3{id: 4, name: "zxy"}
	fmt.Printf("u4 %p \n", &u4)
	u5 := u4 // 值传递，深拷贝
	fmt.Printf("u5 %p \n", &u5)
	u6 := &u4 // 引用传递，浅拷贝
	fmt.Printf("u6 %p \n", u6)

	u5.name = u5.name + "5"
	fmt.Printf("5 u4 %v \n", u4.name) // name不变
	u6.name = u6.name + "6"
	fmt.Printf("6 u4 %v \n", u4.name) // name改变了

	container()

	equals()
}

func container() {
	u1 := User3{id: 1, name: "zxy1"}
	u2 := User3{id: 2, name: "zxy2"}
	slice := []User3{u1, u2}
	fmt.Println(slice)

	slice[0].name = "jasper"
	fmt.Println(slice)

	// map中的struct修改，方式1，局部变量
	umap := make(map[string]User3)
	umap["1"] = u1
	umap["2"] = u2
	fmt.Println(umap)
	//umap["1"].name = "xxx" // 编译错误， map 中的元素是不可寻址的
	u := umap["1"]
	u.name = "xxx" // 可以使用局部变量修改struct中的值
	umap["1"] = u
	fmt.Println(umap)

	// map中的struct修改，方式2，指针
	uptrmap := make(map[string]*User3)
	uptrmap["1"] = &u1
	uptrmap["2"] = &u2
	fmt.Println(uptrmap["1"])
	uptrmap["1"].name = "abc"
	fmt.Println(uptrmap["1"])

}

func equals() {
	u1 := User3{id: 3}
	u2 := User3{id: 3}
	fmt.Println(u1 == u2) // true

	u3 := struct {
		id   int
		name string
		Address
	}{id: 3}
	fmt.Println(u1 == u3) // true

	//u4 := struct {
	//	name string
	//	id   int
	//	Address
	//}{id: 3}
	//fmt.Println(u1 == u4) // 编译出错，字段顺序不一致

	u5 := User3{id: 5}
	fmt.Println(u1 == u5) // false

}
